home *** CD-ROM | disk | FTP | other *** search
- Newsgroups: comp.lang.c
- Path: cwi.nl!dik
- From: dik@cwi.nl (Dik T. Winter)
- Subject: Re: Tough FACTORIAL math problem...
- Message-ID: <DMtsB9.BBz@cwi.nl>
- Sender: news@cwi.nl (The Daily Dross)
- Nntp-Posting-Host: chrysant.cwi.nl
- Organization: CWI, Amsterdam
- References: <4fr8be$ass@news.iconn.net> <31224679.6193@born.com> <4fv16m$cuj@winx03.informatik.uni-wuerzburg.de>
- Date: Thu, 15 Feb 1996 16:25:57 GMT
-
- In article <4fv16m$cuj@winx03.informatik.uni-wuerzburg.de> schoof@informatik.uni-wuerzburg.de (Jochen Schoof) writes:
-
- > in contradiction to what your function said. It is not sufficient
- > to only keep track of the very last relevant digit. The problem
- > mentioned above can be avoided when storing the last two relevant
- > digits and I believe this technique finally is sufficient and
- > still alows to compute the digits for faculties far beyond 1000.
- > Thus the following function should work as desired:
- >
- > int factorial_lsd(int n)
- > {
- > int result=1, i;
- >
- > if(n>1)
- > for(i=1;i<=n;i++)
- > {
- > result*=i;
- > while(result%10==0) result/=10;
- > result%=100;
- > }
- > return temp%10;
- > }
- >
- Also this does not work as desired, even after changing the last "temp"
- to "result". It fails when n=125 (for instance; actually the first
- failure is already at 25). Can you explain why?
- And why 3 last digits will not suffice because that will fail at least
- at n=625 (first failure is actually at 375)? Maintaining the last 4
- digits is good enough, but that will fail at 3125 ;-).
- But wait, this suggests a method using a single temp digit:
-
- int fact_lsd(int n)
- {
- int r = 1, i, i1;
- if(n > 1)
- for(i = 1, i1 = 1; i <= n; i++, i1 = i)
- {
- /* cast out those disturbing fives. */
- while(i1 % 5 == 0)
- {
- i1 /= 5;
- /* multiply by 5 and divide by 10 */
- r >>= 1;
- /* but the result must be even (there are more factors 2 than 5) */
- if(r & 1) r += 5;
- }
- r = (r * i1) % 10;
- }
- }
- return r;
- }
- --
- dik t. winter, cwi, kruislaan 413, 1098 sj amsterdam, nederland, +31205924098
- home: bovenover 215, 1025 jn amsterdam, nederland; http://www.cwi.nl/~dik/
-